home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / blend.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-04  |  16.9 KB  |  637 lines

  1. /* $Id: blend.c,v 3.8 1998/08/16 14:44:56 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: blend.c,v $
  26.  * Revision 3.8  1998/08/16 14:44:56  brianp
  27.  * fixed arithmetic problems in blend_transparency() (Karl Schultz)
  28.  *
  29.  * Revision 3.7  1998/08/05 01:34:40  brianp
  30.  * fixed round-off problem exposed by conformance testing
  31.  *
  32.  * Revision 3.6  1998/07/09 03:15:22  brianp
  33.  * include asm_mmx.h instead of asm-mmx.h
  34.  *
  35.  * Revision 3.5  1998/04/22 00:53:02  brianp
  36.  * fixed a few more IRIX compiler warnings
  37.  *
  38.  * Revision 3.4  1998/03/28 03:57:13  brianp
  39.  * added CONST macro to fix IRIX compilation problems
  40.  *
  41.  * Revision 3.3  1998/03/28 02:03:22  brianp
  42.  * hooked in MMX code
  43.  *
  44.  * Revision 3.2  1998/02/13 04:38:05  brianp
  45.  * optimized blending functions called via BlendFunc function pointer
  46.  *
  47.  * Revision 3.1  1998/02/08 20:16:50  brianp
  48.  * removed unneeded headers
  49.  *
  50.  * Revision 3.0  1998/01/31 20:47:46  brianp
  51.  * initial rev
  52.  *
  53.  */
  54.  
  55.  
  56. #ifdef PC_HEADER
  57. #include "all.h"
  58. #else
  59. #include <assert.h>
  60. #include <stdlib.h>
  61. #include "alphabuf.h"
  62. #include "asm_mmx.h"
  63. #include "blend.h"
  64. #include "context.h"
  65. #include "macros.h"
  66. #include "pb.h"
  67. #include "span.h"
  68. #include "types.h"
  69. #endif
  70.  
  71.  
  72.  
  73. void gl_BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
  74. {
  75.    if (INSIDE_BEGIN_END(ctx)) {
  76.       gl_error( ctx, GL_INVALID_OPERATION, "glBlendFunc" );
  77.       return;
  78.    }
  79.  
  80.    switch (sfactor) {
  81.       case GL_ZERO:
  82.       case GL_ONE:
  83.       case GL_DST_COLOR:
  84.       case GL_ONE_MINUS_DST_COLOR:
  85.       case GL_SRC_ALPHA:
  86.       case GL_ONE_MINUS_SRC_ALPHA:
  87.       case GL_DST_ALPHA:
  88.       case GL_ONE_MINUS_DST_ALPHA:
  89.       case GL_SRC_ALPHA_SATURATE:
  90.       case GL_CONSTANT_COLOR:
  91.       case GL_ONE_MINUS_CONSTANT_COLOR:
  92.       case GL_CONSTANT_ALPHA:
  93.       case GL_ONE_MINUS_CONSTANT_ALPHA:
  94.      ctx->Color.BlendSrc = sfactor;
  95.      break;
  96.       default:
  97.      gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" );
  98.      return;
  99.    }
  100.  
  101.    switch (dfactor) {
  102.       case GL_ZERO:
  103.       case GL_ONE:
  104.       case GL_SRC_COLOR:
  105.       case GL_ONE_MINUS_SRC_COLOR:
  106.       case GL_SRC_ALPHA:
  107.       case GL_ONE_MINUS_SRC_ALPHA:
  108.       case GL_DST_ALPHA:
  109.       case GL_ONE_MINUS_DST_ALPHA:
  110.       case GL_CONSTANT_COLOR:
  111.       case GL_ONE_MINUS_CONSTANT_COLOR:
  112.       case GL_CONSTANT_ALPHA:
  113.       case GL_ONE_MINUS_CONSTANT_ALPHA:
  114.      ctx->Color.BlendDst = dfactor;
  115.      break;
  116.       default:
  117.      gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" );
  118.      return;
  119.    }
  120.  
  121.    ctx->Color.BlendFunc = NULL;
  122.    ctx->NewState |= NEW_RASTER_OPS;
  123. }
  124.  
  125.  
  126.  
  127. /* This is really an extension function! */
  128. void gl_BlendEquation( GLcontext *ctx, GLenum mode )
  129. {
  130.    if (INSIDE_BEGIN_END(ctx)) {
  131.       gl_error( ctx, GL_INVALID_OPERATION, "glBlendEquation" );
  132.       return;
  133.    }
  134.  
  135.    switch (mode) {
  136.       case GL_MIN_EXT:
  137.       case GL_MAX_EXT:
  138.       case GL_LOGIC_OP:
  139.       case GL_FUNC_ADD_EXT:
  140.       case GL_FUNC_SUBTRACT_EXT:
  141.       case GL_FUNC_REVERSE_SUBTRACT_EXT:
  142.      ctx->Color.BlendEquation = mode;
  143.      break;
  144.       default:
  145.      gl_error( ctx, GL_INVALID_ENUM, "glBlendEquation" );
  146.      return;
  147.    }
  148.  
  149.    /* This is needed to support 1.1's RGB logic ops AND
  150.     * 1.0's blending logicops.
  151.     */
  152.    if (mode==GL_LOGIC_OP && ctx->Color.BlendEnabled) {
  153.       ctx->Color.ColorLogicOpEnabled = GL_TRUE;
  154.    }
  155.    else {
  156.       ctx->Color.ColorLogicOpEnabled = GL_FALSE;
  157.    }
  158.  
  159.    ctx->Color.BlendFunc = NULL;
  160.    ctx->NewState |= NEW_RASTER_OPS;
  161. }
  162.  
  163.  
  164.  
  165. void gl_BlendColor( GLcontext *ctx, GLclampf red, GLclampf green,
  166.             GLclampf blue, GLclampf alpha )
  167. {
  168.    ctx->Color.BlendColor[0] = CLAMP( red,   0.0, 1.0 );
  169.    ctx->Color.BlendColor[1] = CLAMP( green, 0.0, 1.0 );
  170.    ctx->Color.BlendColor[2] = CLAMP( blue,  0.0, 1.0 );
  171.    ctx->Color.BlendColor[3] = CLAMP( alpha, 0.0, 1.0 );
  172. }
  173.  
  174.  
  175.  
  176. /*
  177.  * Common transparency blending mode.
  178.  */
  179. static void blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
  180.                 GLubyte rgba[][4], CONST GLubyte dest[][4] )
  181. {
  182.    GLuint i;
  183.    ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
  184.    ASSERT(ctx->Color.BlendSrc==GL_SRC_ALPHA);
  185.    ASSERT(ctx->Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA);
  186.  
  187.    for (i=0;i<n;i++) {
  188.       if (mask[i]) {
  189.      GLint t = rgba[i][ACOMP];  /* t in [0,255] */
  190.  
  191.      if (t == 0) {
  192.         rgba[i][RCOMP] = dest[i][RCOMP];
  193.         rgba[i][GCOMP] = dest[i][GCOMP];
  194.         rgba[i][BCOMP] = dest[i][BCOMP];
  195.         rgba[i][ACOMP] = dest[i][ACOMP];
  196.      }
  197.      else if (t == 255) {
  198.         /* no-op */
  199.      }
  200.      else {
  201.         GLint s = 255 - t;
  202.         GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) >> 8;
  203.         GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) >> 8;
  204.         GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) >> 8;
  205.         GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) >> 8;
  206.         ASSERT(r <= 255);
  207.         ASSERT(g <= 255);
  208.         ASSERT(b <= 255);
  209.         ASSERT(a <= 255);
  210.         rgba[i][RCOMP] = r;
  211.         rgba[i][GCOMP] = g;
  212.         rgba[i][BCOMP] = b;
  213.         rgba[i][ACOMP] = a;
  214.      }
  215.       }
  216.    }
  217. }
  218.  
  219.  
  220.  
  221. /*
  222.  * Add src and dest.
  223.  */
  224. static void blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
  225.                GLubyte rgba[][4], CONST GLubyte dest[][4] )
  226. {
  227.    GLuint i;
  228.    ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
  229.    ASSERT(ctx->Color.BlendSrc==GL_ONE);
  230.    ASSERT(ctx->Color.BlendDst==GL_ONE);
  231.    (void) ctx;
  232.  
  233.    for (i=0;i<n;i++) {
  234.       if (mask[i]) {
  235.      GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
  236.      GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
  237.      GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
  238.      GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
  239.      rgba[i][RCOMP] = MIN2( r, 255 );
  240.      rgba[i][GCOMP] = MIN2( g, 255 );
  241.      rgba[i][BCOMP] = MIN2( b, 255 );
  242.      rgba[i][ACOMP] = MIN2( a, 255 );
  243.       }
  244.    }
  245. }
  246.  
  247.  
  248.  
  249. /*
  250.  * Blend min function  (for GL_EXT_blend_minmax)
  251.  */
  252. static void blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
  253.                GLubyte rgba[][4], CONST GLubyte dest[][4] )
  254. {
  255.    GLuint i;
  256.    ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
  257.    (void) ctx;
  258.  
  259.    for (i=0;i<n;i++) {
  260.       if (mask[i]) {
  261.      rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
  262.      rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
  263.      rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
  264.      rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
  265.       }
  266.    }
  267. }
  268.  
  269.  
  270.  
  271. /*
  272.  * Blend max function  (for GL_EXT_blend_minmax)
  273.  */
  274. static void blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
  275.                GLubyte rgba[][4], CONST GLubyte dest[][4] )
  276. {
  277.    GLuint i;
  278.    ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
  279.    (void) ctx;
  280.  
  281.    for (i=0;i<n;i++) {
  282.       if (mask[i]) {
  283.      rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
  284.      rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
  285.      rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
  286.      rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
  287.       }
  288.    }
  289. }
  290.  
  291.  
  292.  
  293. /*
  294.  * Modulate:  result = src * dest
  295.  */
  296. static void blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
  297.                 GLubyte rgba[][4], CONST GLubyte dest[][4] )
  298. {
  299.    GLuint i;
  300.    (void) ctx;
  301.  
  302.    for (i=0;i<n;i++) {
  303.       if (mask[i]) {
  304.      GLint r = (rgba[i][RCOMP] * dest[i][RCOMP]) >> 8;
  305.      GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8;
  306.      GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8;
  307.      GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8;
  308.      rgba[i][RCOMP] = r;
  309.      rgba[i][GCOMP] = g;
  310.      rgba[i][BCOMP] = b;
  311.      rgba[i][ACOMP] = a;
  312.       }
  313.    }
  314. }
  315.  
  316.  
  317.  
  318. /*
  319.  * General case blend pixels.
  320.  * Input:  n - number of pixels
  321.  *         mask - the usual write mask
  322.  * In/Out:  rgba - the incoming and modified pixels
  323.  * Input:  dest - the pixels from the dest color buffer
  324.  */
  325. static void blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
  326.                GLubyte rgba[][4], CONST GLubyte dest[][4] )
  327. {
  328.    GLfloat rscale = 1.0F / 255.0F;
  329.    GLfloat gscale = 1.0F / 255.0F;
  330.    GLfloat bscale = 1.0F / 255.0F;
  331.    GLfloat ascale = 1.0F / 255.0F;
  332.    GLuint i;
  333.  
  334.    for (i=0;i<n;i++) {
  335.       if (mask[i]) {
  336.      GLint Rs, Gs, Bs, As;  /* Source colors */
  337.      GLint Rd, Gd, Bd, Ad;  /* Dest colors */
  338.      GLfloat sR, sG, sB, sA;  /* Source scaling */
  339.      GLfloat dR, dG, dB, dA;  /* Dest scaling */
  340.      GLfloat r, g, b, a;
  341.  
  342.      /* Source Color */
  343.      Rs = rgba[i][RCOMP];
  344.      Gs = rgba[i][GCOMP];
  345.      Bs = rgba[i][BCOMP];
  346.      As = rgba[i][ACOMP];
  347.  
  348.      /* Frame buffer color */
  349.      Rd = dest[i][RCOMP];
  350.      Gd = dest[i][GCOMP];
  351.      Bd = dest[i][BCOMP];
  352.      Ad = dest[i][ACOMP];
  353.  
  354.      /* Source scaling */
  355.      switch (ctx->Color.BlendSrc) {
  356.         case GL_ZERO:
  357.            sR = sG = sB = sA = 0.0F;
  358.            break;
  359.         case GL_ONE:
  360.            sR = sG = sB = sA = 1.0F;
  361.            break;
  362.         case GL_DST_COLOR:
  363.            sR = (GLfloat) Rd * rscale;
  364.            sG = (GLfloat) Gd * gscale;
  365.            sB = (GLfloat) Bd * bscale;
  366.            sA = (GLfloat) Ad * ascale;
  367.            break;
  368.         case GL_ONE_MINUS_DST_COLOR:
  369.            sR = 1.0F - (GLfloat) Rd * rscale;
  370.            sG = 1.0F - (GLfloat) Gd * gscale;
  371.            sB = 1.0F - (GLfloat) Bd * bscale;
  372.            sA = 1.0F - (GLfloat) Ad * ascale;
  373.            break;
  374.         case GL_SRC_ALPHA:
  375.            sR = sG = sB = sA = (GLfloat) As * ascale;
  376.            break;
  377.         case GL_ONE_MINUS_SRC_ALPHA:
  378.            sR = sG = sB = sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
  379.            break;
  380.         case GL_DST_ALPHA:
  381.            sR = sG = sB = sA =(GLfloat) Ad * ascale;
  382.            break;
  383.         case GL_ONE_MINUS_DST_ALPHA:
  384.            sR = sG = sB = sA = 1.0F - (GLfloat) Ad * ascale;
  385.            break;
  386.         case GL_SRC_ALPHA_SATURATE:
  387.            if (As < 1.0F - (GLfloat) Ad * ascale) {
  388.           sR = sG = sB = (GLfloat) As * ascale;
  389.            }
  390.            else {
  391.           sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
  392.            }
  393.            sA = 1.0;
  394.            break;
  395.         case GL_CONSTANT_COLOR:
  396.            sR = ctx->Color.BlendColor[0];
  397.            sG = ctx->Color.BlendColor[1];
  398.            sB = ctx->Color.BlendColor[2];
  399.            sA = ctx->Color.BlendColor[3];
  400.            break;
  401.         case GL_ONE_MINUS_CONSTANT_COLOR:
  402.            sR = 1.0F - ctx->Color.BlendColor[0];
  403.            sG = 1.0F - ctx->Color.BlendColor[1];
  404.            sB = 1.0F - ctx->Color.BlendColor[2];
  405.            sA = 1.0F - ctx->Color.BlendColor[3];
  406.            break;
  407.         case GL_CONSTANT_ALPHA:
  408.            sR = sG = sB = sA = ctx->Color.BlendColor[3];
  409.            break;
  410.         case GL_ONE_MINUS_CONSTANT_ALPHA:
  411.            sR = sG = sB = sA = 1.0F - ctx->Color.BlendColor[3];
  412.            break;
  413.         default:
  414.            /* this should never happen */
  415.            gl_problem(ctx, "Bad blend source factor in do_blend");
  416.      }
  417.  
  418.      /* Dest scaling */
  419.      switch (ctx->Color.BlendDst) {
  420.         case GL_ZERO:
  421.            dR = dG = dB = dA = 0.0F;
  422.            break;
  423.         case GL_ONE:
  424.            dR = dG = dB = dA = 1.0F;
  425.            break;
  426.         case GL_SRC_COLOR:
  427.            dR = (GLfloat) Rs * rscale;
  428.            dG = (GLfloat) Gs * gscale;
  429.            dB = (GLfloat) Bs * bscale;
  430.            dA = (GLfloat) As * ascale;
  431.            break;
  432.         case GL_ONE_MINUS_SRC_COLOR:
  433.            dR = 1.0F - (GLfloat) Rs * rscale;
  434.            dG = 1.0F - (GLfloat) Gs * gscale;
  435.            dB = 1.0F - (GLfloat) Bs * bscale;
  436.            dA = 1.0F - (GLfloat) As * ascale;
  437.            break;
  438.         case GL_SRC_ALPHA:
  439.            dR = dG = dB = dA = (GLfloat) As * ascale;
  440.            break;
  441.         case GL_ONE_MINUS_SRC_ALPHA:
  442.            dR = dG = dB = dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
  443.            break;
  444.         case GL_DST_ALPHA:
  445.            dR = dG = dB = dA = (GLfloat) Ad * ascale;
  446.            break;
  447.         case GL_ONE_MINUS_DST_ALPHA:
  448.            dR = dG = dB = dA = 1.0F - (GLfloat) Ad * ascale;
  449.            break;
  450.         case GL_CONSTANT_COLOR:
  451.            dR = ctx->Color.BlendColor[0];
  452.            dG = ctx->Color.BlendColor[1];
  453.            dB = ctx->Color.BlendColor[2];
  454.            dA = ctx->Color.BlendColor[3];
  455.            break;
  456.         case GL_ONE_MINUS_CONSTANT_COLOR:
  457.            dR = 1.0F - ctx->Color.BlendColor[0];
  458.            dG = 1.0F - ctx->Color.BlendColor[1];
  459.            dB = 1.0F - ctx->Color.BlendColor[2];
  460.            dA = 1.0F - ctx->Color.BlendColor[3];
  461.            break;
  462.         case GL_CONSTANT_ALPHA:
  463.            dR = dG = dB = dA = ctx->Color.BlendColor[3];
  464.            break;
  465.         case GL_ONE_MINUS_CONSTANT_ALPHA:
  466.            dR = dG = dB = dA = 1.0F - ctx->Color.BlendColor[3] * ascale;
  467.            break;
  468.         default:
  469.            /* this should never happen */
  470.            gl_problem(ctx, "Bad blend dest factor in do_blend");
  471.      }
  472.  
  473.      /* Due to round-off problems we have to clamp against zero. */
  474.      /* Optimization: we don't have to do this for all src & dst factors */
  475.      if (dA < 0.0F)  dA = 0.0F;
  476.      if (dR < 0.0F)  dR = 0.0F;
  477.      if (dG < 0.0F)  dG = 0.0F;
  478.      if (dB < 0.0F)  dB = 0.0F;
  479.      if (sA < 0.0F)  sA = 0.0F;
  480.      if (sR < 0.0F)  sR = 0.0F;
  481.      if (sG < 0.0F)  sG = 0.0F;
  482.      if (sB < 0.0F)  sB = 0.0F;
  483.  
  484.      ASSERT( sR <= 1.0 );
  485.      ASSERT( sG <= 1.0 );
  486.      ASSERT( sB <= 1.0 );
  487.      ASSERT( sA <= 1.0 );
  488.      ASSERT( dR <= 1.0 );
  489.      ASSERT( dG <= 1.0 );
  490.      ASSERT( dB <= 1.0 );
  491.      ASSERT( dA <= 1.0 );
  492.  
  493.      /* compute blended color */
  494.      if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  495.         r = Rs * sR + Rd * dR;
  496.         g = Gs * sG + Gd * dG;
  497.         b = Bs * sB + Bd * dB;
  498.         a = As * sA + Ad * dA;
  499.      }
  500.      else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
  501.         r = Rs * sR - Rd * dR;
  502.         g = Gs * sG - Gd * dG;
  503.         b = Bs * sB - Bd * dB;
  504.         a = As * sA - Ad * dA;
  505.      }
  506.      else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
  507.         r = Rd * dR - Rs * sR;
  508.         g = Gd * dG - Gs * sG;
  509.         b = Bd * dB - Bs * sB;
  510.         a = Ad * dA - As * sA;
  511.      }
  512.  
  513.      /* final clamping */
  514.      rgba[i][RCOMP] = (GLint) CLAMP( r, 0.0F, 255.0F );
  515.      rgba[i][GCOMP] = (GLint) CLAMP( g, 0.0F, 255.0F );
  516.      rgba[i][BCOMP] = (GLint) CLAMP( b, 0.0F, 255.0F );
  517.      rgba[i][ACOMP] = (GLint) CLAMP( a, 0.0F, 255.0F );
  518.       }
  519.    }
  520. }
  521.  
  522.  
  523.  
  524. /*
  525.  * Analyze current blending parameters to pick fastest blending function.
  526.  * Result: the ctx->Color.BlendFunc pointer is updated.
  527.  */
  528. static void set_blend_function(GLcontext *ctx)
  529. {
  530.    GLenum eq = ctx->Color.BlendEquation;
  531.    GLenum src = ctx->Color.BlendSrc;
  532.    GLenum dst = ctx->Color.BlendDst;
  533.  
  534.    if (eq==GL_FUNC_ADD_EXT && src==GL_SRC_ALPHA && dst==GL_ONE_MINUS_SRC_ALPHA) {
  535. #ifdef MMX
  536.       ctx->Color.BlendFunc = gl_mmx_blend_transparency;
  537. #else
  538.       ctx->Color.BlendFunc = blend_transparency;
  539. #endif
  540.    }
  541.    else if (eq==GL_FUNC_ADD_EXT && src==GL_ONE && dst==GL_ONE) {
  542.       ctx->Color.BlendFunc = blend_add;
  543.    }
  544.    else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
  545.          && (src==GL_ZERO && dst==GL_SRC_COLOR))
  546.         ||
  547.         ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
  548.          && (src==GL_DST_COLOR && dst==GL_ZERO))) {
  549.       ctx->Color.BlendFunc = blend_modulate;
  550.    }
  551.    else if (eq==GL_MIN_EXT) {
  552.       ctx->Color.BlendFunc = blend_min;
  553.    }
  554.    else if (eq==GL_MAX_EXT) {
  555.       ctx->Color.BlendFunc = blend_max;
  556.    }
  557.    else {
  558.       ctx->Color.BlendFunc = blend_general;
  559.    }
  560. }
  561.  
  562.  
  563. /*
  564.  * Apply the blending operator to a span of pixels.
  565.  * Input:  n - number of pixels in span
  566.  *         x, y - location of leftmost pixel in span in window coords.
  567.  *         mask - boolean mask indicating which pixels to blend.
  568.  * In/Out:  rgba - pixel values
  569.  */
  570. void gl_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  571.             GLubyte rgba[][4], const GLubyte mask[] )
  572. {
  573.    GLubyte dest[MAX_WIDTH][4];
  574.  
  575.    /* Check if device driver can do the work */
  576.    if (ctx->Color.BlendEquation==GL_LOGIC_OP && !ctx->Color.SWLogicOpEnabled) {
  577.       return;
  578.    }
  579.  
  580.    /* Read span of current frame buffer pixels */
  581.    gl_read_rgba_span( ctx, n, x, y, dest );
  582.  
  583.    if (!ctx->Color.BlendFunc)
  584.       set_blend_function(ctx);
  585.  
  586. #ifndef __STORM__
  587.    (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, dest );
  588. #else
  589.    (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, (CONST GLubyte(*)[4])dest );
  590. #endif
  591. }
  592.  
  593.  
  594.  
  595.  
  596.  
  597. /*
  598.  * Apply the blending operator to an array of pixels.
  599.  * Input:  n - number of pixels in span
  600.  *         x, y - array of pixel locations
  601.  *         mask - boolean mask indicating which pixels to blend.
  602.  * In/Out:  rgba - pixel values
  603.  */
  604. void gl_blend_pixels( GLcontext *ctx,
  605.               GLuint n, const GLint x[], const GLint y[],
  606.               GLubyte rgba[][4], const GLubyte mask[] )
  607. {
  608.    GLubyte dest[PB_SIZE][4];
  609.  
  610.    /* Check if device driver can do the work */
  611.    if (ctx->Color.BlendEquation==GL_LOGIC_OP && !ctx->Color.SWLogicOpEnabled) {
  612.       return;
  613.    }
  614.  
  615.    /* Read pixels from current color buffer */
  616.    (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
  617.  
  618.    if (ctx->RasterMask & ALPHABUF_BIT) {
  619.       gl_read_alpha_pixels( ctx, n, x, y, dest, mask );
  620.    }
  621.    else {
  622.       GLuint i;
  623.       for (i=0; i<n; i++) {
  624.      dest[i][ACOMP] = 255;
  625.       }
  626.    }
  627.  
  628.    if (!ctx->Color.BlendFunc)
  629.       set_blend_function(ctx);
  630.  
  631. #ifndef __STORM__
  632.    (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, dest );
  633. #else
  634.    (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, (CONST GLubyte(*)[4])dest );
  635. #endif
  636. }
  637.